/*
 * Copyright (c) 2002-2003 by OpenSymphony
 * All rights reserved.
 */
package org.jackysoft.workflow;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.jackysoft.entity.WorkflowNode;
import org.jackysoft.util.WorkflowConstant;

/**
 * The core workflow interface.
 * 
 * @author <a href="mailto:plightbo@hotmail.com">Patrick Lightbody</a>
 */
public interface Workflow {

	public static final ThreadLocal<WorkflowNode> WORKFLOW_DESCRIPTOR = new ThreadLocal<WorkflowNode>();
	public static final ThreadLocal<String> WORKFLOW_NAME = new ThreadLocal<String>();
	public static final ThreadLocal<Long> WORKFLOW_ID = new ThreadLocal<Long>();
	public static final ThreadLocal<Integer> ACTION_ID = new ThreadLocal<Integer>();
	public static final ThreadLocal<WorkflowConstant> LOCAL_STATUS = new ThreadLocal<WorkflowConstant>();

	// ~ Methods
	// ////////////////////////////////////////////////////////////////

	/**
	 * Return the state of the specified workflow instance id.
	 * 
	 * @param id
	 *            The workflow instance id.
	 * @return int The state id of the specified workflow
	 */
	public int getEntryState(long id);

	public String getName(long id);

	/**
	 * Get a collection (Strings) of currently defined permissions for the
	 * specified workflow instance.
	 * 
	 * @param id
	 *            id the workflow instance id.
	 * @param inputs
	 *            inputs The inputs to the workflow instance.
	 * @return A List of permissions specified currently (a permission is a
	 *         string name).
	 */
	public List getSecurityPermissions(long id, Map<String,Object> inputs);

	/**
	 * Check if the calling user has enough permissions to initialise the
	 * specified workflow.
	 * 
	 * @param workflowName
	 *            The name of the workflow to check.
	 * @param initialStep
	 *            The id of the initial state to check.
	 * @return true if the user can successfully call initialize, false
	 *         otherwise.
	 */
	public boolean canInitialize(String workflowName, int initialStep);

	/**
	 * Check if the state of the specified workflow instance can be changed to
	 * the new specified one.
	 * 
	 * @param id
	 *            The workflow instance id.
	 * @param newState
	 *            The new state id.
	 * @return true if the state of the workflow can be modified, false
	 *         otherwise.
	 */
	public boolean canModifyEntryState(long id, int newState);

	/**
	 * Modify the state of the specified workflow instance.
	 * 
	 * @param id
	 *            The workflow instance id.
	 * @param newState
	 *            the new state to change the workflow instance to. If the new
	 *            state is
	 *            {@link com.WorkflowRunner.WorkflowEntity.spi.WorkflowEntry.KILLED} or
	 *            {@link com.WorkflowRunner.WorkflowEntity.spi.WorkflowEntry.COMPLETED}
	 *            then all current steps are moved to history steps. If the new
	 *            state is
	 */
	public void changeEntryState(long id, int newState)
			throws WorkflowException;

	/**
	 * Perform retrive the current workfow's action
	 * 
	 * 
	 * */
	public List<ActionItem> getActionItem(long id, Map<String, Object> inputs)
			throws InvalidInputException, WorkflowException;

	/**
	 * 
	 * @param actionId
	 * @param id
	 * @param inputs
	 * */
	public ActionItem getActionItemById(int actionId, long id, Map<String, Object> inputs)
			throws InvalidInputException, WorkflowException;

	/**
	 * Perform an action on the specified workflow instance.
	 * 
	 * @param id
	 *            The workflow instance id.
	 * @param actionId
	 *            The action id to perform (action id's are listed in the
	 *            workflow descriptor).
	 * @param inputs
	 *            The inputs to the workflow instance.
	 * @throws InvalidInputException
	 *             if a validator is specified and an input is invalid.
	 * @throws InvalidActionException
	 *             if the action is invalid for the specified workflow
	 *             instance's current state.
	 */
	public void doAction(long id, int actionId, Map<String,Object> inputs,
			Collection<StepOwner> owners) throws InvalidInputException,
			WorkflowException;

	/**
	 * Executes a special trigger-function using the context of the given
	 * workflow instance id. Note that this method is exposed for Quartz trigger
	 * jobs, user code should never call it.
	 * 
	 * @param id
	 *            The workflow instance id
	 * @param triggerId
	 *            The id of the speciail trigger-function
	 */
	public void executeTriggerFunction(long id, int triggerId)
			throws WorkflowException;

	/**
	 * Initializes a workflow so that it can begin processing. A workflow must
	 * be initialized before it can begin any sort of activity. It can only be
	 * initialized once.
	 * 
	 * @param workflowName
	 *            The workflow name to create and initialize an instance for
	 * @param initialAction
	 *            The initial step to start the workflow
	 * @param inputs
	 *            The inputs entered by the end-user
	 * @throws InvalidRoleException
	 *             if the user can't start this function
	 * @throws InvalidInputException
	 *             if a validator is specified and an input is invalid.
	 * @throws InvalidActionException
	 *             if the specified initial action is invalid for the specified
	 *             workflow.
	 */
	public long initialize(String workflowName, int initialAction, Map<String, Object> inputs)
			throws InvalidRoleException, InvalidInputException,
			WorkflowException, InvalidEntryStateException,
			InvalidActionException;

	/**
	 * Determine if a particular workflow can be initialized.
	 * 
	 * @param workflowName
	 *            The workflow name to check.
	 * @param initialAction
	 *            The potential initial action.
	 * @param inputs
	 *            The inputs to check.
	 * @return true if the workflow can be initialized, false otherwise.
	 */
	boolean canInitialize(String workflowName, int initialAction,
			Map<String, Object> inputs);

	/**
	 * 是为了配合spring，需要对工作流进行配置
	 * */
	Workflow configContext();

}
